using CommunityToolkit.Mvvm.ComponentModel;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
using WinUITest.ViewModels;

namespace WinUITest.Controls;

public sealed partial class UserInfoListControl : UserControl
{
    public ObservableCollection<UserViewModel> DataSource { get => (ObservableCollection<UserViewModel>)GetValue(DataSourceProperty); set => SetValue(DataSourceProperty, value); }
    public static readonly DependencyProperty DataSourceProperty = DependencyProperty.Register(nameof(DataSource), typeof(ObservableCollection<UserViewModel>), typeof(UserInfoListControl), new PropertyMetadata(null, OnDataSourceChange));
    private static void OnDataSourceChange(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is not UserInfoListControl sender) return;
        if (e.OldValue is ObservableCollection<UserViewModel> oldValue)
        {
            oldValue.CollectionChanged -= DataSource_CollectionChanged;
        }
        if (e.NewValue is ObservableCollection<UserViewModel> newValue)
        {
            newValue.CollectionChanged += DataSource_CollectionChanged;
            sender.ViewModel.Clear();
            foreach (UserViewModel item in newValue)
            {
                sender.ViewModel.Add(new(item, sender.RightPanelTemplate));
            }
        }
        void DataSource_CollectionChanged(object? _, NotifyCollectionChangedEventArgs e)
        {
            if (e.Action == NotifyCollectionChangedAction.Add && e.NewItems is not null)
            {
                foreach (object? objItem in e.NewItems)
                {
                    if (objItem is not UserViewModel item) continue;
                    sender.ViewModel.Add(new(item, sender.RightPanelTemplate));
                }
            }
            else if (e.Action == NotifyCollectionChangedAction.Remove && e.OldItems is not null)
            {
                foreach (object? objItem in e.OldItems)
                {
                    if (objItem is not UserViewModel item) continue;
                    sender.ViewModel.Remove(sender.ViewModel.First(m => m.User == item));
                }
            }
            else if (e.Action == NotifyCollectionChangedAction.Reset)
            {
                sender.ViewModel.Clear();
            }
        }
    }
    public DataTemplate? RightPanelTemplate { get => (DataTemplate)GetValue(RightPanelTemplateProperty); set => SetValue(RightPanelTemplateProperty, value); }
    public static readonly DependencyProperty RightPanelTemplateProperty = DependencyProperty.Register(nameof(RightPanelTemplate), typeof(DataTemplate), typeof(UserInfoListControl), new PropertyMetadata(null, OnRightPanelTemplateChange));
    private static void OnRightPanelTemplateChange(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is not UserInfoListControl sender) return;

        if (e.NewValue is DataTemplate newValue)
        {
            foreach (UserInfoListControlItemViewModel item in sender.ViewModel)
            {
                item.RightPanelTemplate = newValue;
            }
        }
        else
        {
            foreach (UserInfoListControlItemViewModel item in sender.ViewModel)
            {
                item.RightPanelTemplate = null;
            }
        }
    }
    public ObservableCollection<UserInfoListControlItemViewModel> ViewModel { get; } = [];
    public UserInfoListControl() => InitializeComponent();
}
public partial class UserInfoListControlItemViewModel(UserViewModel user, DataTemplate? dataTemplate) : ObservableObject
{
    public UserViewModel User { get; } = user;
    [ObservableProperty]
    public partial DataTemplate? RightPanelTemplate { get; set; } = dataTemplate;
}